home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / AEObject-Edition1.0.2 Sample / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-09  |  32.7 KB  |  903 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. *
  3. *  Apple Developer Technical Support
  4. *
  5. *  Menu handling routines
  6. *
  7. *  Program:    AEObject-Edition Sample
  8. *  File:       Menu.c -    C Source
  9. *
  10. *  by:         C.K. Haun <TR>
  11. *
  12. *  Copyright © 1990-1992 Apple Computer, Inc.
  13. *  All rights reserved.
  14. *
  15. *------------------------------------------------------------------------------
  16. * This file handles menu stuff, swapping checkmarks, handling simple dialog 
  17. * boxes, and the like.  If it happens because of a menu selection, it comes through
  18. * here.
  19. *----------------------------------------------------------------------------*/
  20.  
  21. #define __SAMPMENU__
  22.  
  23. #pragma segment Menu
  24.  
  25. #include "Sampdefines.h"
  26. short pItemChecked;
  27.  
  28. static void SampleHelpDialog(void);
  29. static void DoAbout(void);
  30. CursHandle pCursHand = nil;
  31.  
  32.  
  33. #pragma segment Menu
  34. /* DoSelected is called from the main event loop in response to a 
  35. *   MenuSelect or MenuKey action.  Some events are handled here,
  36. *   some just set options.
  37. */
  38.  
  39. /* the long passed is the result from MenuSelect or MenuKey */
  40. /* this passes back a Boolean, which I don't use right now. */
  41. Boolean DoSelected(long val)
  42. {
  43.     short loval, hival;
  44.     Boolean temp = false;
  45.     Str63 menuText;
  46.     windowCHandle tempWC;
  47.     short tempActionOut;
  48.     loval = LoWord(val);
  49.     hival = HiWord(val);
  50.     if(FrontWindow())tempWC = (windowCHandle)GetWRefCon(FrontWindow());    
  51.     switch (hival) {                                        /* switch off the menu number selected */
  52.         case kGetDataSubmenu:
  53.             SendGetData(loval);
  54.             break;
  55.         case kSetDataSubmenu:
  56.             SendSetData(loval);
  57.         break;
  58.         case kAppleMenu:                                    /* Apple menu */
  59.             if (loval != kAboutItem) {                               /* if this was not About, it's a DA */
  60.                 DoDaCall(gAppleMenuHandle, loval);
  61.             } else {
  62.                 DoAbout();                                  /* do about box */
  63.             }
  64.             break;
  65.         case kFileMenu:                                     /* File menu */
  66.             switch (loval) {
  67.                 WindowPtr tempW;
  68.                 AliasHandle tempAlias;                      /* for SaveAs */
  69.                 windowCHandle tempName;
  70.                 case kNewItem:
  71.                     if (!(tempW = AddNewWindow(true)))      /* Call AddNewWindow.  If it fails, tell */
  72.                         Alert(kNoMoreWindows, (ModalFilterProcPtr)standardAlertFilter);         /* user why */
  73.                     else
  74.                         ChangePlane(tempW);
  75.                     break;
  76.                 case kOpenItem:
  77.                     OpenFile(nil);                          /* open a file, nil says that I am not passing a */
  78.                     /* FileSpec, promt the user for a name */
  79.                     break;
  80.                 case kCloseItem:                            /* call the close procedure for this window */
  81.                     (ProcPtr)((*tempWC)->closeMe)(FrontWindow());
  82.                     break;
  83.                 case kSaveItem:                             /* call the save procedure for this window */
  84.                     HLock((Handle)(windowCHandle)((WindowPeek)FrontWindow())->refCon);
  85.                     (ProcPtr)((*tempWC)->saveMe)(tempWC, FrontWindow());
  86.                     HUnlock((Handle)(windowCHandle)((WindowPeek)FrontWindow())->refCon);
  87.                     break;
  88.                 case kSaveAsItem:                           /* save under a different name */
  89.                     HLock((Handle)tempWC);
  90.                     tempName = (windowCHandle)GetWRefCon(FrontWindow());
  91.                     /* save off the old alias in case the person cancels */
  92.                     tempAlias = (*tempName)->fileAliasHandle;
  93.                     /* get an empty handle and store it in the alias place, this tells the Save */
  94.                     /* function that this file has not yet been saved, so put up a SF box */
  95.                     (*tempName)->fileAliasHandle = (AliasHandle)NewHandle(0);
  96.                     (ProcPtr)((*tempWC)->saveMe)(tempWC, FrontWindow());
  97.                     /* see if they really saved (by checking the size of the alias) and if they have */
  98.                     /* get rid of the alias you saved */
  99.                     if (GetHandleSize((Handle)(*tempName)->fileAliasHandle) == nil) {
  100.                         DisposHandle((Handle)(*tempName)->fileAliasHandle);
  101.                         (*tempName)->fileAliasHandle = tempAlias;
  102.                     } else {
  103.                         DisposHandle((Handle)tempAlias);
  104.                     }
  105.                     HUnlock((Handle)tempWC);
  106.                     break;
  107.                     
  108.                 case kPrintItem:
  109.                     PrintIt(FrontWindow(), true);
  110.                     break;
  111.                 case kPreferences:
  112.                     DoPreferences();
  113.                     break;
  114.                 case kQuitItem:
  115.                     PrepQuit();                             /* Call PrepQuit, which sets our quit flag, so we */
  116.                     /* quit the next time through the event loop. The */
  117.                     /* AEQuit handler also calls this routine */
  118.                     break;
  119.             }
  120.             break;
  121.         case kEditMenu:
  122.             /* edit menu junk */
  123.             switch (loval) {
  124.                 case kUndoItem:
  125.                     UndoLast();                             /* Undoes the last action in the frontmost window */
  126.                     break;
  127.                     /* all the C/C/P stuff acts _first_ on any active TextEdit records. */
  128.                     /* if there aren't any, then it goes to other stuff */
  129.                 case kCutItem:
  130.                     if (!CutText()){
  131.                         if((*tempWC)->hasSelection){
  132.                         CutGraphic(tempWC);
  133.                         } else {
  134.                         CutSubscription();}}
  135.                     break;
  136.                 case kCopyItem:
  137.                     if (!CopyText()){
  138.                         if((*tempWC)->hasSelection){
  139.                         CopyGraphic(tempWC);
  140.                         } else {
  141.                         CopySubscription();}}
  142.                     break;
  143.                 case kPasteItem:
  144.                     /* pasting text has precidence over subscriptions.  Just because I felt like it */
  145.                     /* vary to suit the needs of your users and application */
  146.                     if (!PasteText())
  147.                         PasteSubscription();
  148.                     break;
  149.                 case kClearItem:
  150.                     /* Clear item acts as 'cancel' for the selected section */
  151.                     if (!ClearText()){
  152.                         if((*tempWC)->hasSelection){
  153.                         ClearGraphic(tempWC);
  154.                         } else {
  155.                         DeleteSubscriber();}}
  156.                     break;
  157.                 case kPublishItem:
  158.                     /* see if there is any text */
  159.                     if (HasTESelection((windowCHandle)GetWRefCon(FrontWindow())))
  160.                         CreatePublisher(kGenericTEXTWord, false, nil);
  161.                     else
  162.                         CreatePublisher(kGenericPICTWord, false, nil);        /* in Publish.c */
  163.                     break;
  164.                 case kSubscribeItem:
  165.                     DoSubscribe();                          /* in Subscribe.c */
  166.                     break;
  167.                 case kSoptionsItem:
  168.                     DoOptions(gShowingSecHandle);           /* in Subscribe.c.  Same */
  169.                     /* function is called for a publish or subscribe section */
  170.                     break;
  171.                 case kBorders:
  172.                     if (gShowingAll) {
  173.                         gShowingAll = false;
  174.                         GetIndString(menuText, kGeneralStrings, kShowBString);
  175.                         
  176.                         SetItem(gEditMenuHandle, kBorders, menuText);
  177.                         
  178.                         /* and get rid of any currently shown borders, even the */
  179.                         /* last clicked in one */
  180.                         DeBorderSelection();
  181.                         KillTextBorders();
  182.                     } else {
  183.                         gShowingAll = true;
  184.                         GetIndString(menuText, kGeneralStrings, kHideBString);                        
  185.                         SetItem(gEditMenuHandle, kBorders, menuText);
  186.                         ShowAllTextBorders();
  187.                     }
  188.                     /* make sure they get redrawn */
  189.                     InvalRect(&(FrontWindow()->portRect));                    
  190.                     break;
  191.                 case kClapNum:
  192.                     if (((WindowPeek)FindClipWindow())->visible) {
  193.                         CloseClip(FindClipWindow());
  194.                     } else {
  195.                         ShowWindow(FindClipWindow());
  196.                         AddToWindowMenu(FindClipWindow(), nil);
  197.                         ChangePlane(FindClipWindow());
  198.                         GetIndString(menuText, kGeneralStrings, kHideClipString);                        
  199.                         SetItem(gEditMenuHandle, kClapNum, menuText);
  200.                         
  201.                     }
  202.                     break;
  203.                     
  204.             }                                               /* edit menu switch */
  205.             break;
  206.         case kToolsMenu:
  207.             switch (loval) {
  208.                 /* Clean this up, this is silly, I say, this is silly son..... */
  209.                 case kLineItem:
  210.                     tempActionOut = kDrawLine;
  211.                     break;
  212.                 case kRectItem:
  213.                     tempActionOut = kDrawRect;
  214.                     break;
  215.                 case kOvalItem:
  216.                     tempActionOut = kDrawOval;
  217.                     break;
  218.                 case kTextBoxItem:
  219.                     tempActionOut = kTextBox;
  220.                     break;
  221.                 case kSelectItem:
  222.                     tempActionOut = kSelectStuff;
  223.                     break;
  224.                     
  225.             }
  226.             /* these set the current action for the front window, set the */
  227.             /* cursor for the selected tool, and check the correct menu item */
  228.             KillSelection((windowCHandle)GetWRefCon(FrontWindow()));
  229.             SetCurAction(tempActionOut);
  230.             SetMyCursor(loval);
  231.             SwitchChecks(loval);
  232.             break;
  233.         case kAEMenu:
  234.             switch (loval) {
  235.                 case kInteractionItem:
  236.                     SetInteractionLevels();
  237.                     break;
  238.                 case kAddressItem:
  239.                     SetTargetAddress();
  240.                     break;
  241.                 case kReplyItem:
  242.                     SetReplyMode();
  243.                     break;
  244.                 case kShowAEWind:
  245.                     ToggleAEWindow();
  246.                     break;
  247.                     /* set the characteristics that will make up the object specifier */
  248.                     /* for the window to be acted upon.  Jeez, pendantic enough, or what? */
  249.                     
  250.                 case kWindowObjChar:
  251.                 case kTextObjectChar:
  252.                 case kShapeObjectChar:
  253.                     DoObjectDefinition((loval - kWindowObjChar) + kSetWindowObject);
  254.                     break;
  255.                 case kSendGetDataAE:
  256.                     /* has sub-menu, should never be returned */
  257.                     break;
  258.                     
  259.                 case kSendSetDataAE:
  260.                     /* has sub-menu, should never be returned */
  261.                     break;
  262.                 default:
  263.                     
  264.                     break;
  265.             }
  266.             break;
  267.         case kEditionMenu:
  268.         DoEditionAdditional(loval);
  269.         break;
  270.         case kWindowMenu:
  271.             WindowToFront(loval,nil);
  272.             break;
  273.         case kColorMenu:
  274.  
  275.         CheckItem(gColorMenuHandle, gCurrentColor,false);
  276.         CheckItem(gColorMenuHandle, loval,true);
  277.         if(loval == kCustomColorItem){Point where = {-1,-1};
  278.         Str255 thewords;
  279.         RGBColor newColor;
  280.         GetIndString(thewords,kGeneralStrings,kCPick);
  281.         if(GetColor(where,thewords,&gColorArray[gCurrentColor],&newColor))gColorArray[kCustomColorItem] = newColor;
  282.         }
  283.         gCurrentColor = loval;
  284.                 
  285.         
  286.         break;
  287.         case kHMHelpMenuID:
  288.             /* I only care about this one item.  If anything else is returned here, I don't know what */
  289.             /* it is, so I leave it alone.  Remember, the Help Manager chapter syas that */
  290.             /* Apple reserves the right to add and change things in the Help menu */
  291.             if (loval == gHelpItem)
  292.                 SampleHelpDialog();
  293.             break;
  294.             
  295.     }
  296.     HiliteMenu(0);
  297.     return(temp);   /* I have never actually use this return value in 6 years, but I might some day.  */
  298.     /* I always put it in because it _could_ be real handy */
  299. }
  300.  
  301. /* end DoSelected */
  302.  
  303. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  304. /* like to perform some action or just know when a DA is opened in your */
  305. /* layer.  Can be handy to track memory problems when a DA is opened */
  306. /* with an Option-open */
  307. void DoDaCall(MenuHandle themenu, long theit)
  308. {
  309.     long qq;
  310.     char DAname[255];
  311.     GetItem(themenu, theit, &DAname);
  312.     qq = OpenDeskAcc(DAname);
  313. }
  314.  
  315. /* end DoDaCall */
  316.  
  317. /* PrepQuit sets the stop flag.  Called from the menu or from the */
  318. /* quit AppleEvent handler.  It also calls the close function on all open windows, and */
  319. /* cancels the quit if the user stops things */
  320. /* Also unregisters the ClipBoard section, if one exists */
  321. OSErr PrepQuit(void)
  322. {
  323.     WindowPtr tempFront = mWindList;
  324.     windowCHandle tempWCH;
  325.     gStop = true;
  326.     while (tempFront) {
  327.         WindowPtr tempHolder;
  328.         tempHolder = (WindowPtr)((WindowPeek)tempFront)->nextWindow;
  329.         tempWCH = (windowCHandle)GetWRefCon(tempFront);
  330.         (ProcPtr)((*tempWCH)->closeMe)(tempFront);          /* call this closing routine */
  331.         tempFront = tempHolder;                             /* yeah, yeah , a little duplication.  */
  332.         if (gStop == false)
  333.             break;                                          /* if this is false, they hit cancel in the close routine */
  334.     }
  335.     if (gStop) {
  336.         extern short gClipHasContents;
  337.         extern SectionHandle gClipSection;
  338.         /* clear the clipboard */
  339.         /* if it has a section, we have to tell the Edition Manager we're done with it */
  340.         if (gClipHasContents == kClipHasSub) {
  341.             UnRegisterSection(gClipSection);
  342.             DisposHandle((Handle)(*gClipSection)->alias);
  343.             DisposeHandle((Handle)gClipSection);
  344.             gClipSection = nil;
  345.             gClipHasContents = kClipEmpty;
  346.         }
  347.         return(noErr);                                      /* quit will happen */
  348.     } else {
  349.         return(userCanceledErr);
  350.     }                                                       /* user stopped the termination */
  351. }
  352.  
  353. /* end PrepQuit */
  354.  
  355. /* SetUndo sets the text of the Undo item based on the last action in */
  356. /* the current window, if fromRecord is true, else use*/
  357. /* undoNow */
  358. void SetUndo(short undoNow, Boolean fromRecord)
  359. {Str255 undoString;
  360.     windowCHandle temp;
  361.     if (FrontWindow() == nil) {
  362.         GetIndString(undoString, kUndoStringsRes, 1);
  363.         SetItem(gEditMenuHandle, kUndoItem, &undoString);
  364.         DisableItem(gEditMenuHandle, kUndoItem);
  365.     } else {
  366.         temp = (windowCHandle)GetWRefCon(FrontWindow());
  367.         if (fromRecord)
  368.             undoNow = (*temp)->undoAction;
  369.         else
  370.             (*temp)->undoAction = undoNow;
  371.         GetIndString(undoString, kUndoStringsRes, undoNow + 1);
  372.         SetItem(gEditMenuHandle, kUndoItem, &undoString);
  373.         if (undoNow)
  374.             EnableItem(gEditMenuHandle, kUndoItem);
  375.         else
  376.             DisableItem(gEditMenuHandle, kUndoItem);
  377.     }
  378. }
  379.  
  380. /* end SetUndo */
  381.  
  382. /* SetMyCursor sets the cursor to the correct shape for the */
  383. /* tool in use */
  384. void SetMyCursor(short myCurs)
  385. {
  386.     if (pCursHand != nil) {
  387.         ReleaseResource((Handle)pCursHand);
  388.         pCursHand = nil;
  389.     }
  390.     if (myCurs == 0) {
  391.         InitCursor();
  392.     } else {
  393.         switch (myCurs) {
  394.             case kLineItem:
  395.                 pCursHand = GetCursor(crossCursor); /* in the system file */
  396.                 break;
  397.             case kRectItem:
  398.             case kTextBox:
  399.             case kOvalItem:
  400.                 pCursHand = (CursHandle)GetResource('CURS', 126 + myCurs);
  401.                 break;
  402.             case kSelectItem:
  403.                 pCursHand = (CursHandle)GetResource('CURS', 131);
  404.                 break;
  405.         }
  406.         SetCursor(*pCursHand);
  407.     }
  408. }
  409.  
  410. /* end SetMyCursor */
  411.  
  412. /* SwitchChecks sets the checking of the tool menu items  */
  413. void SwitchChecks(short itemNow)
  414. {
  415.     Boolean how;
  416.     if (pItemChecked == itemNow) {                          /* is this item currently checked?  If so */
  417.         how = false;                                        /* uncheck it and set action to nil */
  418.         SetCurAction(kNoAction);
  419.         InitCursor();
  420.         pItemChecked = 0;
  421.     } else {
  422.         CheckItem(gToolMenuHandle, pItemChecked, false);
  423.         pItemChecked = itemNow;
  424.         how = true;
  425.     }
  426.     CheckItem(gToolMenuHandle, itemNow, how);
  427. }
  428.  
  429. /* end SwitchChecks */
  430.  
  431. /* SetCurAction sets the action value in the window record */
  432. void SetCurAction(short actionIn)
  433. {
  434.     if (FrontWindow() != nil) {
  435.         windowCHandle shortname = (windowCHandle)GetWRefCon(FrontWindow());
  436.         HLock((Handle)shortname);
  437.         (*shortname)->currentAction = actionIn;
  438.         HUnlock((Handle)shortname);
  439.     }
  440. }
  441.  
  442. /* end SetCurAction */
  443.  
  444. void SetWMenus(Boolean how)
  445. {
  446.     short qq;
  447.     if (how) {
  448.         EnableItem(gFileMenuHandle, kCloseItem);
  449.         EnableItem(gFileMenuHandle, kPrintItem);
  450.         EnableItem(gFileMenuHandle, kSaveItem);
  451.         EnableItem(gFileMenuHandle, kSaveAsItem);
  452.         EnableItem(gEditMenuHandle, kSubscribeItem);
  453.         EnableItem(gToolMenuHandle, 0);
  454.         for (qq = 1; qq < 5; qq++) {
  455.             EnableItem(gToolMenuHandle, qq);
  456.         }
  457.     } else {
  458.         DisableItem(gFileMenuHandle, kCloseItem);
  459.         DisableItem(gFileMenuHandle, kPrintItem);
  460.         DisableItem(gFileMenuHandle, kSaveItem);
  461.         DisableItem(gFileMenuHandle, kSaveAsItem);
  462.         DisableItem(gEditMenuHandle, kSubscribeItem);
  463.         DisableItem(gToolMenuHandle, 0);                    /* kill this whole thing */
  464.     }
  465.     DrawMenuBar();
  466. }
  467.  
  468. /* end SetWMenus */
  469.  
  470. /* AdjustMenus is called right before MenuSelect or MenuKey to set the state of */
  471. /* the menu items for the frontmost window.  */
  472. void AdjustMenus(windowCHandle tempCH,WindowPtr currentWindow)
  473. {
  474.     Str63 menuText;
  475.     register qq;
  476.     Str63 item, name;
  477.     short count;
  478.     short wKind;
  479.     /* Do we currently */
  480.     /* have an area selected? */
  481.     if(currentWindow)
  482.         wKind = ((WindowPeek)currentWindow)->windowKind;
  483.     if (tempCH && ((*tempCH)->hasSelection || HasTESelection(tempCH)))            /* Yes, enable the Publish item */
  484.         EnableItem(gEditMenuHandle, kPublishItem);
  485.     else                                                    /* No, dim the publish item */
  486.         DisableItem(gEditMenuHandle, kPublishItem);
  487.     
  488.     /* Next, are we showing a border around a subscriber or */
  489.     /* publisher? If so, then we allow the user to bring up */
  490.     /* the Options dialog */
  491.     if (gShowPub || gShowSub) {
  492.         EnableItem(gEditMenuHandle, kSoptionsItem);
  493.         EnableItem(gEditionMenuHandle,kGetSecInfo);
  494.     } else {
  495.         DisableItem(gEditMenuHandle, kSoptionsItem);
  496.         DisableItem(gEditionMenuHandle,kGetSecInfo);
  497.     }
  498.        /* is there a document or AEStatus window in front? */
  499. if (currentWindow != nil && (wKind == kDocumentWindow || wKind == kAEStatusWindow)) {
  500.         EnableItem(gFileMenuHandle, kSaveItem);
  501.         /* this following little if is based on a pickiness I have personally */
  502.         /* If the window has not yet been saved, include an ellipsis in the 'Save…' */
  503.         /* item, since the standard file box will be coming up. */
  504.         /* if it has been saved, then no dots, just 'Save' */
  505.         /* since there won't be a dialog */
  506.         if (GetHandleSize((Handle)(*tempCH)->fileAliasHandle) == nil) {
  507.             GetIndString(menuText, kGeneralStrings, kSaveDotsString);
  508.             SetItem(gFileMenuHandle, kSaveItem, menuText);
  509.         } else {
  510.             GetIndString(menuText, kGeneralStrings, kSaveNDotsString);
  511.             SetItem(gFileMenuHandle, kSaveItem, menuText);
  512.         }
  513.         } else {
  514.           DisableItem(gFileMenuHandle, kSaveItem);
  515.         }        
  516.     if (currentWindow != nil && wKind == kDocumentWindow ) {   /* is there a document window in front? */
  517.             /* I'm only allowing a text box if there are no other objects. */
  518.        if ((*tempCH)->boxHandle != nil || (*tempCH)->numShapes)
  519.             DisableItem(gToolMenuHandle, kTextBoxItem);
  520.         else
  521.             EnableItem(gToolMenuHandle, kTextBoxItem);
  522.         
  523.     } else {
  524.       
  525.         /* make sure the undo and show borders items are right */
  526.         SetUndo(nil, nil);
  527.         GetIndString(menuText, kGeneralStrings, kShowBString);
  528.         SetItem(gEditMenuHandle, kBorders, menuText);
  529.         DisableItem(gEditMenuHandle, kBorders);
  530.     }
  531.     /* if there is a subscriber, or a subscription on the clipboard, or a TEselection enable the edit commands */
  532.     if (tempCH && ((*tempCH)->hasSelection || gShowSub || HasTESelection(tempCH))) {
  533.         EnableItem(gEditMenuHandle, kCutItem);
  534.         EnableItem(gEditMenuHandle, kCopyItem);
  535.         EnableItem(gEditMenuHandle, kClearItem);
  536.     } else {
  537.         DisableItem(gEditMenuHandle, kCutItem);
  538.         DisableItem(gEditMenuHandle, kCopyItem);
  539.         DisableItem(gEditMenuHandle, kClearItem);
  540.     }
  541. /* uuuh, sorry, this 'if' got a little out of hand */
  542. if ((tempCH != nil) && (gClipHasContents == kClipHasSub || (gClipHasContents == kClipHasText && (*tempCH)->boxHandle != nil)) &&  wKind == kDocumentWindow) {
  543.         EnableItem(gEditMenuHandle, kPasteItem);
  544.     } else {
  545.         DisableItem(gEditMenuHandle, kPasteItem);
  546.     }
  547.     if (currentWindow) {
  548.         EnableItem(gFileMenuHandle, kCloseItem);
  549.     } else {
  550.         DisableItem(gFileMenuHandle, kCloseItem);
  551.     }
  552.     /* check frontmost window in the window menu */
  553.     if (currentWindow) {
  554.         count = CountMItems(gWindowMenuHandle);
  555.         GetWTitle(currentWindow, name);
  556.         for (qq = 1; qq < count + 1; qq++)
  557.             CheckItem(gWindowMenuHandle, qq, false);
  558.         for (qq = 1; qq < count + 1; qq++) {
  559.             GetItem(gWindowMenuHandle, qq, &item);
  560.             if (EqualString(item, name, false, false)) {
  561.                 CheckItem(gWindowMenuHandle, qq, true);
  562.             }
  563.         }
  564.     } 
  565. }
  566.  
  567. /* Just an example, since I had to have something to do when you select */
  568. /* my Help item */
  569. void SampleHelpDialog(void)
  570. {
  571.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  572.     short itemhit = 0;
  573.     SetDialogDefaultItem(tdial, ok);
  574.     while (itemhit != 1) {
  575.         ModalDialog((ModalFilterProcPtr)standardDialogFilter, &itemhit);
  576.     }
  577.     DisposDialog(tdial);
  578. }
  579.  
  580. /* The about box.   */
  581. void DoAbout(void)
  582. {
  583.     DialogPtr tdial = GetNewDialog(kAboutBox, nil, (WindowPtr)-1);
  584.     short hitItem = 0;
  585.     short tempItem;
  586.     Handle tempHandle;
  587.     Rect tempRect;
  588.     GetDItem(tdial, kBorderArea, &tempItem, &tempHandle, &tempRect);
  589.     SetDItem(tdial, kBorderArea, tempItem, (Handle)BorderDefault, &tempRect);
  590.     GetDItem(tdial, kArrowArea, &tempItem, &tempHandle, &tempRect);
  591.     SetDItem(tdial, kArrowArea, tempItem, (Handle)ArrowArea, &tempRect);
  592.     ShowWindow(tdial);
  593.     while (hitItem != ok) {
  594.         ModalDialog((ModalFilterProcPtr)aboutFilter, &hitItem);
  595.     }
  596.     DisposDialog(tdial);
  597. }
  598.  
  599. /* this filter does the icon animation */
  600. pascal Boolean aboutFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
  601. {
  602.     Boolean returnVal = false;
  603.     static short pOffset = 1;
  604.     static Boolean pMovingRight = true;
  605.     
  606.     static long count;
  607.     long tilticks;
  608.     Handle topIcon, bottomIcon;
  609.     short tempItem;
  610.     Handle tempHandle;
  611.     Rect tempRect;
  612.     Rect idleRect, iconRect;
  613.     WindowPtr tempPort;
  614. #define kReturnKey 0xd
  615. #define kEnterKey 3
  616.     GetPort(&tempPort);
  617.     SetPort(theDialog);
  618.     if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
  619.         switch (theEvent->message & charCodeMask) {
  620.             case kReturnKey:
  621.             case kEnterKey:                                 /* enter key */
  622.                 /* This filters for Return or Enter as item 1, and Esc as item 2 */
  623.                     *itemHit = 1;                           /* change whatever the current item is to the OK item */
  624.                 /* now we need to invert the button */
  625.                 GetDItem(theDialog, ok, &tempItem, &tempHandle, &tempRect);
  626.                 HiliteControl(SnatchHandle(theDialog, ok), inButton);
  627.                 Delay(8, &tilticks);                        /* wait about 8 ticks so they can see it */
  628.                 HiliteControl(SnatchHandle(theDialog, ok), false);
  629.                 returnVal = true;
  630.                 break;
  631.             default:
  632.                 break;
  633.         }
  634.     } else {
  635.         /* Do fancy animation.  Hey, this sample is big, took a while to write, I should have */
  636.         /* a fancy about box.  Anyway, it only took 1/2 hour (I used DialogBits.c) */
  637.         GetDItem(theDialog, kArrowArea, &tempItem, &tempHandle, &tempRect);
  638.         idleRect.top = tempRect.top;
  639.         idleRect.bottom = idleRect.top + 32;
  640.         idleRect.left = ((((tempRect.right - tempRect.left) / 2))+tempRect.left)-16;
  641.         idleRect.right = idleRect.left + 32;
  642.         iconRect = idleRect;
  643.         if (pMovingRight) {
  644.             /* going <- -> */
  645.             topIcon = GetIcon(129);
  646.             bottomIcon = GetIcon(130);
  647.         } else {
  648.             topIcon = GetIcon(130);
  649.             bottomIcon = GetIcon(129);
  650.             
  651.         }
  652.         OffsetRect(&iconRect, 1 * pOffset, 0);
  653.         PlotIcon(&iconRect, topIcon);
  654.         ReleaseResource(topIcon);
  655.         iconRect = idleRect;
  656.         OffsetRect(&iconRect, -1 * pOffset, 0);
  657.         iconRect.bottom = tempRect.bottom;
  658.         iconRect.top = iconRect.bottom - 32;
  659.         PlotIcon(&iconRect, bottomIcon);
  660.         ReleaseResource(bottomIcon);
  661.         pMovingRight ? pOffset++ : pOffset--;
  662.         if (pMovingRight) {
  663.             if (iconRect.left <= tempRect.left)
  664.                 pMovingRight = false;
  665.         } else {
  666.             if (iconRect.right >= tempRect.right)
  667.                 pMovingRight = true;
  668.         }
  669.     }
  670.     SetPort(tempPort);
  671.     return(returnVal);
  672. }
  673.  
  674. /* borders the default button.  Not needed with the new Dialog Manager calls, see Tech Note #304 */
  675. pascal void BorderDefault(WindowPtr dwind, short dinum)
  676. {
  677. #pragma unused (dinum)
  678.     short itemtype;
  679.     Handle itemhandle;
  680.     Rect borderRect;
  681.     GetDItem(dwind, ok, &itemtype, &itemhandle, &borderRect);
  682.     /* ok is defined as 1 in the interfaces.  If you'd like another item outlined, */
  683.     /* change this number, of course. */
  684.     InsetRect(&borderRect, -4, -4);
  685.     PenSize(3, 3);
  686.     FrameRoundRect(&borderRect, 16, 16);
  687.     PenSize(1, 1);
  688. }
  689.  
  690. /* user item for the area the arrows traverse.  doesn't do much */
  691. pascal void ArrowArea(WindowPtr dwind, short dinum)
  692. {
  693. #pragma unused (dinum)
  694.     short itemtype;
  695.     Handle itemhandle;
  696.     Rect borderRect;
  697.     GetDItem(dwind, dinum, &itemtype, &itemhandle, &borderRect);
  698.     EraseRect(&borderRect);
  699. }
  700.  
  701. /* Our preferences dialog box */
  702. pascal void FrameBox(WindowPtr rDial, short dinum);
  703. void DoPreferences(void)
  704. {
  705.     DialogPtr tdial = CommonDStart(kPreferencesBox, nil, nil);
  706.     short kindI;
  707.     Handle HandL;
  708.     Rect itemRect;
  709.     short hitItem = 0;
  710.     
  711.     ShowWindow(tdial);
  712.     /* Set the controls to the previously stored preferences */
  713.     SetCtlValue(SnatchHandle(tdial, kBringAEForwardCheck), gPreferences.bringAEUp);
  714.     SetCtlValue(SnatchHandle(tdial, kVerboseCheck), gPreferences.verboseAE);
  715.     SetCtlValue(SnatchHandle(tdial, kSaveWindCheck), gPreferences.saveWindDef);
  716.     SetCtlValue(SnatchHandle(tdial, kSaveTextCheck), gPreferences.saveTextDef);
  717.     SetCtlValue(SnatchHandle(tdial, kSaveShapeCheck), gPreferences.saveShapeDef);
  718.     SetCtlValue(SnatchHandle(tdial, kSaveInteractCheck), gPreferences.saveInteract);
  719.     SetCtlValue(SnatchHandle(tdial, kSaveTargetCheck), gPreferences.saveTarget);
  720.     SetCtlValue(SnatchHandle(tdial, kSaveReplyCheck), gPreferences.saveReply);
  721.     
  722.  
  723.  
  724.     GetDItem(tdial, kFBox1, &kindI, &HandL, &itemRect);
  725.     SetDItem(tdial, kFBox1, userItem, (Handle)FrameBox, &itemRect);
  726.     GetDItem(tdial, kFBox2, &kindI, &HandL, &itemRect);
  727.     SetDItem(tdial, kFBox2, userItem, (Handle)FrameBox, &itemRect);
  728.     GetDItem(tdial, kFBox3, &kindI, &HandL, &itemRect);
  729.     SetDItem(tdial, kFBox3, userItem, (Handle)FrameBox, &itemRect);
  730.  
  731.  
  732.     /* run the dialog */
  733.     while (hitItem != ok && hitItem != cancel) {
  734.         ModalDialog((ModalFilterProcPtr)standardDialogFilter, &hitItem);
  735.         switch (hitItem) {
  736.             case 9:
  737.             Alert(350,(ModalFilterProcPtr)standardAlertFilter);
  738.             break;
  739.             case kBringAEForwardCheck:
  740.             case kVerboseCheck:
  741.             case kSaveWindCheck:
  742.             case kSaveTextCheck:
  743.             case kSaveShapeCheck:
  744.             case kSaveInteractCheck:
  745.             case kSaveTargetCheck:
  746.             case kSaveReplyCheck:
  747.             /* if they hit a checkbox, just toggle state */
  748.                 SetCtlValue(SnatchHandle(tdial, hitItem), (GetCtlValue(SnatchHandle(tdial, hitItem)) ? 0 : 1));
  749.                 break;
  750.             default:
  751.                 break;
  752.         }
  753.     }
  754.     if (hitItem == ok) {
  755.         /* generate our new preferences */
  756.         gPreferences.bringAEUp = GetCtlValue(SnatchHandle(tdial, kBringAEForwardCheck));
  757.         gPreferences.verboseAE = GetCtlValue(SnatchHandle(tdial, kVerboseCheck));
  758.         gPreferences.saveWindDef = GetCtlValue(SnatchHandle(tdial, kSaveWindCheck));
  759.         gPreferences.saveTextDef = GetCtlValue(SnatchHandle(tdial, kSaveTextCheck));
  760.         gPreferences.saveShapeDef = GetCtlValue(SnatchHandle(tdial, kSaveShapeCheck));
  761.         gPreferences.saveInteract = GetCtlValue(SnatchHandle(tdial, kSaveInteractCheck));
  762.         gPreferences.saveTarget = GetCtlValue(SnatchHandle(tdial, kSaveTargetCheck));
  763.         gPreferences.saveReply = GetCtlValue(SnatchHandle(tdial, kSaveReplyCheck));        
  764.         gPreferences.prefsChanged = true;
  765.     }
  766.     DisposDialog(tdial);
  767. }
  768.  
  769.  
  770. /* Draws a greay outline and some text around related items in a DialogBox */
  771. pascal void FrameBox(WindowPtr rDial, short dinum)
  772. {
  773.     Str63 wordsAre;
  774.     
  775.     Rect framer;
  776.     Rect tempR;
  777.     short itemIs;
  778.     short widthY;
  779.     Point thePen;
  780.     Point start, end;
  781.     Handle yeah;
  782.     GetIndString(&wordsAre, 129, dinum - 12);
  783.     GetDItem(rDial, dinum, &itemIs, &yeah, &framer);
  784.     widthY = StringWidth(&wordsAre);
  785.     
  786.     /* do the sides first */
  787.     /* left */
  788.     start.h = framer.left;
  789.     start.v = framer.top;
  790.     end.h = framer.left;
  791.     end.v = framer.bottom;
  792.     MoveTo(start.h, start.v);
  793.     LineTo(end.h, end.v);
  794.     MakeRect(&start, &end, &tempR);
  795.     PenPat(&qd.gray);
  796.     PenMode(notPatBic);
  797.     PaintRect(&tempR);
  798.     PenMode(srcCopy);
  799.     PenPat(&qd.black);
  800.     /* bottom */
  801.     start.h = framer.left;
  802.     start.v = framer.bottom;
  803.     end.h = framer.right;
  804.     end.v = framer.bottom;
  805.     MoveTo(start.h, start.v);
  806.     LineTo(end.h, end.v);
  807.     MakeRect(&start, &end, &tempR);
  808.     PenPat(&qd.gray);
  809.     PenMode(notPatBic);
  810.     PaintRect(&tempR);
  811.     PenMode(srcCopy);
  812.     PenPat(&qd.black);
  813.     /* right */
  814.     start.h = framer.right;
  815.     start.v = framer.bottom;
  816.     end.h = framer.right;
  817.     end.v = framer.top;
  818.     MoveTo(start.h, start.v);
  819.     LineTo(end.h, end.v);
  820.     start.h -= 3;
  821.     MakeRect(&start, &end, &tempR);
  822.     PenPat(&qd.gray);
  823.     PenMode(notPatBic);
  824.     PaintRect(&tempR);
  825.     PenMode(srcCopy);
  826.     PenPat(&qd.black);
  827.     
  828.     /* top line to start of text */
  829.     start.h = framer.left;
  830.     start.v = framer.top;
  831.     end.h = start.h + 10;
  832.     end.v = framer.top;
  833.     MoveTo(start.h, start.v);
  834.     LineTo(end.h, end.v);
  835.     start.h -= 3;
  836.     MakeRect(&start, &end, &tempR);
  837.     PenPat(&qd.gray);
  838.     PenMode(notPatBic);
  839.     PaintRect(&tempR);
  840.     PenMode(srcCopy);
  841.     PenPat(&qd.black);
  842.     MoveTo(end.h+3, end.v + 4);
  843.     DrawString(&wordsAre);
  844.     GetPen(&thePen);
  845.     /* end of text to corner */
  846.     start.h = thePen.h+4;
  847.     start.v = thePen.v - 4;
  848.     end.h = framer.right;
  849.     end.v = thePen.v - 4;
  850.     MoveTo(start.h, start.v);
  851.     LineTo(end.h, end.v);
  852.     start.h -= 3;
  853.     MakeRect(&start, &end, &tempR);
  854.     PenPat(&qd.gray);
  855.     PenMode(notPatBic);
  856.     PaintRect(&tempR);
  857.     PenMode(srcCopy);
  858.     PenPat(&qd.black);
  859.     
  860.     
  861. }
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871. /* This handles the EM Stuff menu */
  872. void DoEditionAdditional(short which)
  873. {
  874. EditionInfoRecord tempRecord;
  875. Str63 orgDate;
  876. Str63 modDate;
  877. Str15 typeCreator;
  878.    switch (which) {
  879.         case kExpandedItem:
  880.             gExpanded = gExpanded ? false : true;
  881.             CheckItem(gEditionMenuHandle, kExpandedItem, gExpanded);
  882.             
  883.             break;
  884.         case kGetSecInfo:
  885.             
  886.             GetEditionInfo(gShowingSecHandle, &tempRecord);
  887.             IUDateString(tempRecord.crDate, longDate, orgDate);
  888.             IUDateString(tempRecord.mdDate, longDate, modDate);
  889.             typeCreator[0]=9;
  890.             BlockMove((Ptr)&tempRecord.fdCreator, (Ptr)&typeCreator[1], 4);
  891.             typeCreator[5] = '/';
  892.             BlockMove((Ptr)&tempRecord.fdType, (Ptr)&typeCreator[6], 4);
  893.             ParamText(orgDate, modDate, typeCreator,tempRecord.container.theFile.name);
  894.             Alert(kEdInfo, (ModalFilterProcPtr)standardAlertFilter);
  895.             break;
  896.                   }
  897.  
  898. }
  899.  
  900.  
  901.  
  902. #undef __SAMPMENU__
  903.